﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CCWin;
using CCWin.SkinControl;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using CCWin.SkinClass;
using System.Collections;
using GroupChat2013.Main.Controls;
using GroupChat2013.Logic;
using GroupChat2013.Main.Properties;
using GroupChat2013.Interface;
using GroupChat2013.Entity;
using GroupChat2013.Service;

namespace GroupChat2013.Main
{
    public partial class FrmChatRecord : CCSkinMain
    {
        #region 变量

        /// <summary>
        /// 当前登录用户
        /// </summary>
        public UserInfo m_CurrentUser
        {
            get { return EngineContext.Current.CurrUserInfo; }
        }

        /// <summary>
        /// 是否结束线程标志
        /// </summary>
        private bool m_HasItem = true;

        /// <summary>
        /// 需要接收的图片文件
        /// </summary>
        public Queue m_NeedRecPictures;

        /// <summary>
        /// 线程同步信号
        /// </summary>
        private AutoResetEvent m_AutoReset = new AutoResetEvent(false);

        /// <summary>
        /// 下载图片线程
        /// </summary>
        private Thread m_DownImgThread;

        private IMessage messageManage;

        /// <summary>
        /// 聊天信息操作
        /// </summary>
        private ChatType chatType;

        private string ID;

        private string TITLEFORMAT = "{0} ";

        private int pageIndex = 0;

        private int totalCount = 0;

        private int totalPage
        {
            get
            {
                if (PageSize == 0)
                    return 0;

                return totalCount % PageSize > 0 ? totalCount / PageSize + 1 : totalCount / PageSize;
            }
        }

        #endregion

        private int PageSize
        {
            get
            {
                int size = 20;
                int.TryParse(tbSize.Text, out size);
                return size;
            }
        }

        #region 构造函数

        public FrmChatRecord(IMessage messageManage, ChatType chatType, string id, string name)
        {
            InitializeComponent();
            this.messageManage = messageManage;
            this.chatType = chatType;
            ID = id;

            this.Text = "与" + name + "的信息记录";
        }

        private void FrmChatRecord_Load(object sender, EventArgs e)
        {
            InitDownloadImgQueue();

            FirstPage_Click(FirstPage, null);
        }

        #endregion

        #region 下载本地没有的聊天记录内里的图片

        /// <summary>
        /// 初始化下载图片线程
        /// </summary>
        public void InitDownloadImgQueue()
        {
            m_NeedRecPictures = Queue.Synchronized(new Queue());
            m_DownImgThread = new Thread(new ThreadStart(() =>
            {
                while (m_HasItem)
                {
                    if (m_NeedRecPictures.Count > 0)
                    {
                        MyPicture pic = m_NeedRecPictures.Dequeue() as MyPicture;
                        if (pic != null)
                        {
                            string fullPath = Path.Combine(EngineContext.Current.FilePathManager.ImagePath, pic.MD5 + ".gif");
                            messageManage.m_ImageUpload.DownlodImage(pic.MD5, fullPath);
                            if (File.Exists(fullPath))
                            {
                                pic.Image = Image.FromFile(fullPath);
                            }
                            else
                            {
                                pic.Image = Resources.error;
                            }

                            this.Invalidate();
                        }
                    }
                    else
                    {
                        m_AutoReset.WaitOne();
                    }
                }
            }));
            m_DownImgThread.IsBackground = true;
            m_DownImgThread.Start();
        }

        #endregion

        #region 将用户对话消息插入消息记录区

        private void AppendToRichTextBox(List<MessageInfo> mcList)
        {
            this.txtRecord.Clear();

            mcList.Reverse();

            //发送成功后将接收到的信息添加到消息记录区
            if (mcList != null && mcList.Count > 0)
            {
                messageManage.ParseMessageContent(mcList);

                mcList.ForEach(x =>
                {
                    if (x.MessageContent != null)
                    {
                        if (x.MessageContent.FromId == m_CurrentUser.UserId)
                            this.SendToRichTextBox(x.MessageContent, true);
                        else
                            this.ReceiveToRichTextBox(x.MessageContent);
                    }
                });
            }
        }

        /// <summary>
        /// 讲接收到的消息写入消息记录区
        /// </summary>
        /// <param name="msg"></param>
        private void ReceiveToRichTextBox(MessageContent msg)
        {
            MsgToRichTextBox(msg, false, true);
        }

        /// <summary>
        /// 将自己发送的消息加入 RichTextBox 控件
        /// </summary>
        /// <param name="msg">消息类</param>
        /// <param name="IsSend">标记是发送消息还是收到消息</param>
        /// <param name="title">标记如果是发送状态下 是否发送成功</param>
        private void SendToRichTextBox(MessageContent msg, bool isSendSucc)
        {
            MsgToRichTextBox(msg, true, isSendSucc);
        }

        /// <summary>
        /// 将用户对话消息加入 RichTextBox 控件
        /// </summary>
        /// <param name="msg">消息类</param>
        /// <param name="IsSend">标记是发送消息还是收到消息</param>
        /// <param name="title">标题（用户名+用户ID）</param>
        private void MsgToRichTextBox(MessageContent msg, bool IsSend, bool isSendSucc)
        {
            string title = string.Format(TITLEFORMAT, msg.FromName);
            int iniPos = txtRecord.TextLength;//获得当前记录richBox中最后的位置
            title += msg.CreateTime.ToString();
            Color titleColor = Color.Green;

            if (!IsSend)//如果是收到消息
                titleColor = Color.Blue;

            txtRecord.AppendText(" " + title);
            txtRecord.Select(iniPos, txtRecord.TextLength - iniPos);
            txtRecord.SelectionFont = new Font("宋体", 10);
            txtRecord.SelectionColor = titleColor;

            txtRecord.AppendText("\n  ");

            iniPos = txtRecord.TextLength;//获得当前记录richBox中最后的位置

            //如果消息中有图片，则添加图片
            if (!string.IsNullOrEmpty(msg.ImageInfo))
            {
                string[] imagePos = msg.ImageInfo.Split('|');
                int addPos = 0;//
                int currPos = 0;//当前正要添加的文本位置
                int textPos = 0;
                for (int i = 0; i < imagePos.Length - 1; i++)
                {
                    string[] imageContent = imagePos[i].Split(',');//获得图片所在的位置、图片名称 
                    currPos = Convert.ToInt32(imageContent[0]);//获得图片所在的位置

                    txtRecord.AppendText(AddHeadSpace(msg.Content.Substring(textPos, currPos - addPos)));
                    txtRecord.SelectionStart = txtRecord.TextLength;

                    textPos += currPos - addPos;
                    addPos += currPos - addPos;

                    Image image = null;
                    if (txtRecord.GetPicture(imageContent[1]) != null)
                        image = txtRecord.GetPicture(imageContent[1]).Image;
                    else
                    {
                        string fileName = Path.Combine(EngineContext.Current.FilePathManager.ImagePath, imageContent[1] + ".gif");
                        if (System.IO.File.Exists(fileName)) //如果本地已经有此文件已经存在 
                            image = System.Drawing.Image.FromFile(fileName);
                    }

                    if (imageContent[1].Length < 32 && image == null)
                        image = System.Drawing.Image.FromFile(Application.StartupPath + @"\face\" + imageContent[1] + ".gif");
                    if (image == null)
                    {
                        image = Properties.Resources.wite;
                        MyPicture pic = txtRecord.addGifControl(imageContent[1], image);
                        m_NeedRecPictures.Enqueue(pic);
                    }
                    else
                    {
                        txtRecord.addGifControl(imageContent[1], image);
                    }

                    addPos++;
                }
                this.txtRecord.AppendText(msg.Content.Substring(textPos, msg.Content.Length - textPos) + "\n");
            }
            else //如果消息中没有图片，则直接添加消息文本
            {
                txtRecord.AppendText(AddHeadSpace(msg.Content) + "\n");
            }

            txtRecord.Select(iniPos, txtRecord.TextLength - iniPos);
            txtRecord.SelectionFont = msg.Font;
            txtRecord.SelectionColor = msg.Color;

            txtRecord.Select(txtRecord.TextLength, 0);
            txtRecord.ScrollToCaret();

            //激活下载图片线程
            if (m_NeedRecPictures.Count > 0)
            {
                m_AutoReset.Set();
            }
        }

        private string AddHeadSpace(string content)
        {
            return content.Replace("\n", "\n   ");
        }

        #endregion

        #region 释放资源

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Release()
        {
            try { m_DownImgThread.Abort(); }
            catch { }

            this.txtRecord.RemoveAllGifControl();

            m_NeedRecPictures.Clear();
        }

        #endregion

        #region 方法

        /// <summary>
        /// 第一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FirstPage_Click(object sender, EventArgs e)
        {
            pageIndex = 0;

            ChatRecordInfo data = GetRecords();
            totalCount = data.total;

            SetControl();
            AppendToRichTextBox(data.data);
        }

        /// <summary>
        /// 前一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PrevPage_Click(object sender, EventArgs e)
        {
            pageIndex--;

            ChatRecordInfo data = GetRecords();
            totalCount = data.total;

            SetControl();
            AppendToRichTextBox(data.data);
        }

        /// <summary>
        /// 下一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NextPage_Click(object sender, EventArgs e)
        {
            if (pageIndex < totalPage)
            {
                pageIndex++;

                ChatRecordInfo data = GetRecords();
                totalCount = data.total;

                SetControl();
                AppendToRichTextBox(data.data);
            }
        }

        /// <summary>
        /// 最后一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LastPage_Click(object sender, EventArgs e)
        {
            pageIndex = totalPage;

            pageIndex--;
            ChatRecordInfo data = GetRecords();
            totalCount = data.total;

            SetControl();
            AppendToRichTextBox(data.data);
        }

        private void tbClose_Click(object sender, EventArgs e)
        {
            Release();

            this.Close();
        }

        private void SetControl()
        {
            tbPageIndex.Text = (pageIndex + 1).ToString();
            PrevPage.Enabled = FirstPage.Enabled = pageIndex > 0;
            NextPage.Enabled = LastPage.Enabled = pageIndex < totalPage;
            toolStripLabel4.Text = "页/" + totalPage + "页";

            this.txtRecord.RemoveAllGifControl();

            m_NeedRecPictures.Clear();
        }

        private ChatRecordInfo GetRecords()
        {
            if (chatType == ChatType.Group)
                return ServiceUrlProxy.GetInstance().GetGroupChatMsgRecord(ID, pageIndex, PageSize, m_CurrentUser.CID);
            else if (chatType == ChatType.User)
                return ServiceUrlProxy.GetInstance().GetUserMessage(ID, pageIndex, PageSize, m_CurrentUser.CID);
            else return new ChatRecordInfo();
        }

        public void SetLocation(Rectangle rectangle)
        {
            this.Left = rectangle.X + rectangle.Width;
            this.Top = rectangle.Y;

            this.Height = rectangle.Height;
        }

        public void Show(Rectangle rectangle)
        {
            SetLocation(rectangle);

            this.Show();
        }

        #endregion

        private void tbPageIndex_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                int index = 0;
                if (int.TryParse(tbPageIndex.Text, out index) && index > 0)
                {
                    pageIndex = index - 1;

                    ChatRecordInfo data = GetRecords();
                    totalCount = data.total;

                    AppendToRichTextBox(data.data);
                }
                else
                {
                    MessageBoxEx.Show("请输入正确的页码");
                    return;
                }
            }
        }

        private void txtRecord_LinkClicked(object sender, LinkClickedEventArgs e)
        {
            string url = GroupChat2013.Common.Helper.AddUrlParams(e.LinkText, "cid=" + EngineContext.Current.CurrUserInfo.CID);
            FrmGroup.OpenWithChrome(url);
        }
    }
}
